#ifndef BUFFEROBJECT_H
#define BUFFEROBJECT_H
#include "Troll3D_global.h"
#include "GL/glew.h"

#include "Mesh/Vertex.h"
/*! @brief Store the buffers used for storing vertex and index on GPU side
 *
 *  Basically, an IBO store the vertex position in the VBO when a draw call is needed
 *  This avoid multiple vertex to be added multiples times
 *  An IBO must containt short data (16 bit)
 *
 *  @brief VBO stand for "Vertex buffer object" and is used to store data on the GPU Side.
 *
 *  The goal here is to use only one VBO wich will be used to store all the vertex's attributes,
 *  such as position(P), normal(N), color(C), texture coordinate/uv (U)
 *
 *  The datas attributes will be interleave, so the VBO will store attribute this way :
 *  PNCUPNCUPNCU
 *  ATI recommand a vertex attribute to be 32-bytes multiple (32, 64,128), so, I should not hesitate
 *  to add blank float in my VBO. A float is 4 bytes.
 *
 *  VBO Workflow : All shape write their vertices in the VBO, wich can be access
 *  by every class as Vbo is a static one.
 *  Alwo, I use instead of using only one vbo and ibo, 2 are used. The application will write on one, and, when writing operation is over, it'll
 *  become the displaying one and vice versa
 */

class TROLL3DSHARED_EXPORT BufferObject
{
    /********************************
    /*          Public
    /********************************/
    public :

        /********************************
        /*          Constructors
        /********************************/

            BufferObject();

        /********************************
        /*          Methods
        /********************************/

            /********************************
            /*          Static
            /********************************/

                static  void    Initialize();
                static  void    Bind();
                static  void    FeedBuffers();

        /********************************
        /*          Properties
        /********************************/


    /********************************
    /*          Private
    /********************************/
    private :

        /********************************
        /*          Static
        /********************************/

            /********************************
            /*          Methods
            /********************************/

                static  void    InitVBO();
                static  void    InitIBO();

                static  void    FeedVBO();
                static  void    FeedIBO();

                static  void    BindVBO();
                static  void    BindIBO();


                /*! @brief After the buffer used for data insertion is full, I set it as
                 *          the new displaying buffer. The last one is now the new buffer used for
                 *      the next data insertion */
                static  void    Swap();


            /********************************
            /*          Properties
            /********************************/

                static  GLuint  s_WritingVBO;
                static  GLuint  s_DisplayingVBO;

                static  GLuint  s_WritingIBO;
                static  GLuint  s_DisplayingIBO;

};

#endif // BUFFEROBJECT_H
